package com.runningboy.es_demo.service;

import com.runningboy.es_demo.dto.DocDto;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author Runningboy
 * @Date 2020/6/24 20:17
 * @Version 1.0
 */
@Service
public class ESService {

    @Autowired
    private TransportClient esClient;

    /**
     * 根据文档ID获取文档
     * @param id
     * @return
     */
    public GetResponse getDocById(String id){
      GetResponse response = esClient.prepareGet("man","girl",id).get();
      return response;
    }

    /**
     * 往ES存储文档：需要把存储的数据构造json格式
     * @param docDto
     */
    public ResponseEntity addDoc(DocDto docDto) {

        try {
            XContentBuilder content = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("name",docDto.getName())
                    .field("country",docDto.getCountry())
                    .field("age",docDto.getAge())
                    .endObject();

            IndexResponse response = esClient.prepareIndex("man","girl")
                    .setSource(content)
                    .get();

            return  new ResponseEntity(response.getResult(),HttpStatus.OK);

        }catch (IOException e){
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 根据ID删除文档
     * @param id
     * @return
     */
    public ResponseEntity del(String id){
        DeleteResponse response = esClient.prepareDelete("man","girl",id)
                .get();
        return  new ResponseEntity(response,HttpStatus.OK);
    }

    /**
     * 根据ID更新数据
     * @param id
     * @param docDto
     * @return
     */
    public ResponseEntity update(String id,DocDto docDto){

        UpdateRequest updateRequest = new UpdateRequest("man","girl",id);
        try{
            XContentBuilder content = this.getContent(XContentFactory.jsonBuilder().startObject(),docDto);//开始构建json结构数据
            content.endObject();
            updateRequest.doc(content);

        }catch (IOException e){
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }

        try{
            UpdateResponse response = esClient.update(updateRequest).get();
            return new ResponseEntity(response,HttpStatus.OK);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /*public ResponseEntity queryByCountry(String country){
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if(country != null){
            boolQuery.must(QueryBuilders.matchQuery("country",country));
        }

    }*/

    /**
     * 复合查询，例如：查询国籍是中国或者china的，同时查询年龄段20-30的
     * 这里用到布尔查询,用布尔查询和filter实现范围查询
     * @param country
     * @param ltAge
     * @param gtAge
     * @return
     */
    public SearchResponse query(String country, Integer gtAge, Integer ltAge){
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if(country != null){
            //matchPhraseQuery：短语匹配
            boolQuery.must(QueryBuilders.matchPhraseQuery("country",country));
        }

        //年龄范围查询
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age")
                .from(gtAge);
        if (ltAge != null && ltAge >0){
            rangeQuery.to(ltAge);
        }
        boolQuery.filter(rangeQuery);

        SearchRequestBuilder search = esClient.prepareSearch("man") //索引
                .setTypes("girl","boy","boyl") //类型
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                .setQuery(boolQuery)  //复合查询的类型
                .setFrom(0)  //从第几页开始
                .setSize(10);  //每页多少条数据

        System.out.println(search);

        SearchResponse response = search.get();

        return response;

//        List<Map<String,Object>> result = new ArrayList<>();
//        for(SearchHit hit : response.getHits()){
//            result.add(hit.getSource());
//        }
//        return new ResponseEntity(result,HttpStatus.OK);
    }








    private XContentBuilder getContent(XContentBuilder content,DocDto docDto) throws IOException {

        if(docDto.getName() != null && !docDto.getName().isEmpty()){
            content.field("name",docDto.getName());
        }

        if(docDto.getCountry() != null && !docDto.getCountry().isEmpty()){
            content.field("country",docDto.getCountry());
        }

        if(docDto.getAge() != null && docDto.getAge() > 0){
            content.field("age",docDto.getAge());
        }

        return  content;
    }

}
